#pragma once
#include "Socket.hpp"
#include "Connection.hpp"
#include "IOService.hpp"
#include "Reactor.hpp"
#include "Calculator.hpp"
using namespace MySocketModule;

/** 连接管理器 */
namespace EpollModule
{
    //主要是listen_socket
    class Listener : public Connection
    {
    private:
        uint16_t _port;
        std::shared_ptr<Socket> _listensocket;
    public:
        Listener(int port)
            :_port(port)
            ,_listensocket(std::make_shared<TcpSocket>())
        {
            _listensocket->BuildTcpSocketMethod(_port);
            SetSocketFd(_listensocket->GetSockfd());    //设置connection的fd
            SetEvent(EPOLLIN | EPOLLET);                //添加关心事件、ET模式
            //设置非阻塞读
            SetNoBlock(_listensocket->GetSockfd());
        }

        virtual void Sender()  override
        {

        }

        virtual void Recver() override
        {
            //listen进行accept，本质也是IO
            //listenfd就绪，此时你怎么知道有多少连接要建立呢？
            //循环读
            while (true)
            {
                InetAddr client;
                int myerrno = 0;
                //1.此时，accept就不会阻塞了
                int newfd = _listensocket->AcceptOrDie(&client,&myerrno);
                // cout << "newfd:" << newfd << endl; 
                //accept成功
                if(newfd > 0)
                {
                    //不能直接读取，将新的fd，添加至epoll模型
                    LOG(LogGrade::DEBUG) << "acceptr success..";
                    //2.此时都是普通fd，构建conn
                    auto conn = make_shared<IOService>(newfd);
                    //注册数据的处理方法
                    conn->RegisterHandle(Entry);
                    //3.添加至epoll
                    GetOwner()->InsertConnection(conn);
                }
                else
                {
                    if(myerrno == EAGAIN || myerrno == EWOULDBLOCK)
                    {
                        //底层数据已读完
                        LOG(LogGrade::NORMAL) << "accepted all connecion...";
                        break;
                    }
                    else if(myerrno & EINTR)
                    {
                        //被信号中断，从新读
                        LOG(LogGrade::NORMAL) << "accept interrupt by signal...";
                        continue;   
                    }
                    else
                    {
                        LOG(LogGrade::NORMAL) << "accept error...";
                        Excepter();
                        break;
                    }
                }
            }
        }

        virtual void Excepter() override
        {
            LOG(LogGrade::ERROR) << "客户端连接可能结束，进行异常处理: " << _sockfd;
            //出现了异常，我们什么也做不了，只能从epll中移除，关闭连接
            GetOwner()->DelConnection(_sockfd);
        }

        int GetFd()
        {
            return _listensocket->GetSockfd();
        }

        ~Listener()
        {
            _listensocket->Close();
        }
    };
}